﻿using System;
using System.Text.RegularExpressions;

namespace Kernelx.Contexts.Defaults.Sequences._Internals
{

    internal class SequeBracket : BaseBracket
    {
        internal const string _Name = "seq";

        internal static string Slot => $"[[{_Name}]]";

        public override string Name => _Name;

        public override Output Input(string formula) => new SequeOutput(Convert.ToInt32(formula));

        internal class SequeOutput : Output
        {
            private readonly int _length;

            public SequeOutput(int length) : base(null)
            {
                _length = length;
                Pattern = $@"(?<{_Name}>\d{{{_length},}})";
            }

            public string Pattern { get; private set; }

            private int _seq = 1;
            public SequeOutput Seed(int seque)
            {
                _seq = seque;
                return this;
            }
            public override string Get() => _seq.ToString().PadLeft(_length, '0');

        }

    }

    internal class ParameterBracket : BaseBracket
    {
        const string _name = "args";

        internal static string Label = $"@{_name}";


        public override string Name => _name;

        const string _pattern = @"^(?<name>[\w-]+)@(?<length>\d+)$";

        public override Output Input(string formula)
        {
            var match = Regex.Match(formula, _pattern);
            if (match.Success)
            {
                var name = match.Groups["name"].Value;
                var len = Convert.ToInt32(match.Groups["length"].Value);
                return new ParameterOutput(name, len);
            }
            else
                throw new ApplicationException($"此公式[{{args:{formula}}}]不正确, 示例: {{args:code@6}}");
        }

        internal class ParameterOutput : Output
        {
            public string ParaName { get; private set; }
            public string Slot => $"[[{ParaName}]]";

            private readonly int _length;

            public ParameterOutput(string paraName, int length) : base(null)
            {
                ParaName = paraName;
                _length = length;
            }

            private string _value;
            public ParameterOutput Checkup(string value)
            {
                if (!string.IsNullOrEmpty(value) && value.Length == _length)
                    _value = value;
                else
                    throw new ApplicationException($"args:参数{ParaName}的实参值:{value}的长度不符合指定约束");
                return this;
            }

            public override string Get() => _value;

        }

    }

}
